package com.bkgy.anno.aspect;

import com.bkgy.anno.Log;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 日志切面，用于记录方法执行时间
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

    /**
     * 定义切点
     */
    @Pointcut("@annotation(com.bkgy.anno.Log)")
    public void logPointcut() {
    }

    /**
     * 记录方法执行时间
     */
    @Around("logPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        Log logAnnotation = method.getAnnotation(Log.class);
        String module = logAnnotation.module();
        String description = logAnnotation.description();

        // 记录开始时间
        long startTime = System.currentTimeMillis();

        // 执行目标方法
        Object result;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            // 记录异常信息
            log.error("\n\n方法执行异常 - 模块: 【{}】, 描述: 【{}】, 方法: 【{}.{}】, 异常: {}\n\n",
                    module, description, signature.getDeclaringTypeName(),
                    signature.getName(), e.getMessage());
            throw e;
        } finally {
            // 计算执行时间
            long executionTime = System.currentTimeMillis() - startTime;

            // 记录执行时间日志
            log.info("\n\n方法执行时间 - 模块: 【{}】, 描述: 【{}】, 方法: 【{}.{}】, 耗时: {}ms\n\n",
                    module, description, signature.getDeclaringTypeName(),
                    signature.getName(), executionTime);
        }

        return result;
    }
}

